﻿using MathTutorPro.Data.DAL;
using MathTutorPro.Data.Entities;
using MathTutorPro.Hepler;
using MathTutorPro.Hubs;
using MathTutorPro.Models.Requests;
using MathTutorPro.Models.Responses;
using MathTutorPro.Services.Interfaces;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;

namespace MathTutorPro.Services.Implementations
{
    /// <summary>
    /// 群组聊天服务实现
    /// </summary>
    public class GroupChatService : IGroupChatService
    {
        private readonly GroupChatDal _groupDal;
        private readonly GroupChatMessageDal _messageDal;
        private readonly GroupChatMemberDal _memberDal;
        private readonly ClassDal _classDal;
        private readonly IHubContext<GroupChatHub> _hubContext;
        private readonly ILogger<GroupChatService> _logger;

        public GroupChatService(
            GroupChatDal groupDal,
            GroupChatMessageDal messageDal,
            GroupChatMemberDal memberDal,
            ClassDal classDal,
            IHubContext<GroupChatHub> hubContext,
            ILogger<GroupChatService> logger)
        {
            _groupDal = groupDal;
            _messageDal = messageDal;
            _memberDal = memberDal;
            _classDal = classDal;
            _hubContext = hubContext;
            _logger = logger;
        }

        /// <summary>
        /// 创建群组
        /// </summary>
        public async Task<int> CreateGroupAsync(string userId, GroupCreateRequest request)
        {
            // 验证请求
            if (string.IsNullOrEmpty(request.GroupName))
                throw new ArgumentException("群组名称不能为空");

            // 创建群组
            var group = new ChatGroup
            {
                GroupName = request.GroupName,
                DescText = request.DescText,
                CreateUserId = userId,
                CreateTime = DateTime.Now,
                ClassId = request.ClassId,
                IsActive = true
            };

            var createdGroup = await _groupDal.CreateGroupAsync(group);

            // 添加创建者为群组成员
            await _memberDal.AddMemberAsync(new ChatGroupMember
            {
                ChatGroupId = createdGroup.Id,
                UserId = userId,
                JoinTime = DateTime.Now
            });

            // 如果指定了班级，添加班级学生为群组成员
            if (request.ClassId.HasValue)
            {
                // 验证班级是否存在且用户是否有权限
                if (!await _classDal.ExistsAsync(request.ClassId.Value, userId))
                    throw new UnauthorizedAccessException("无权操作该班级");

                // 获取班级学生ID列表
                var studentIds = await _classDal.GetClassStudentIdsAsync(request.ClassId.Value);
                
                // 添加班级学生为群组成员
                foreach (var studentId in studentIds)
                {
                    if (studentId != userId) // 跳过创建者，因为已经添加过了
                    {
                        await _memberDal.AddMemberAsync(new ChatGroupMember
                        {
                            ChatGroupId = createdGroup.Id,
                            UserId = studentId,
                            JoinTime = DateTime.Now
                        });
                    }
                }
            }
            // 如果指定了成员列表，添加指定成员
            else if (request.MemberIds != null && request.MemberIds.Any())
            {
                foreach (var memberId in request.MemberIds)
                {
                    if (memberId != userId) // 跳过创建者，因为已经添加过了
                    {
                        await _memberDal.AddMemberAsync(new ChatGroupMember
                        {
                            ChatGroupId = createdGroup.Id,
                            UserId = memberId,
                            JoinTime = DateTime.Now
                        });
                    }
                }
            }

            return createdGroup.Id;
        }

        /// <summary>
        /// 获取用户的群组列表
        /// </summary>
        public async Task<IEnumerable<GroupResponse>> GetUserGroupsAsync(string userId)
        {
            var groups = await _groupDal.GetGroupsByUserIdAsync(userId);
            return groups.Select(g => new GroupResponse
            {
                GroupId = g.Id,
                GroupName = g.GroupName,
                DescText = g.DescText,
                CreatedBy = g.CreateUserId,
                CreatedAt = g.CreateTime
            });
        }

        /// <summary>
        /// 获取群组消息
        /// </summary>
        public async Task<IEnumerable<MessageResponse>> GetGroupMessagesAsync(string userId, int groupId, int page = 1, int pageSize = 20)
        {
            // 验证用户是否是群组成员
            var group = await _groupDal.GetGroupByIdAsync(groupId);
            if (group == null)
                throw new KeyNotFoundException("群组不存在");

            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            var messages = await _messageDal.GetMessagesByGroupAsync(groupId);
            return messages.Select(m => new MessageResponse
            {
                MessageId = m.Id,
                GroupId = m.ChatGroupId,
                UserId = m.SenderId,
                Content = m.Content,
                CreatedAt = (DateTime)m.SentTime
            });
        }

        /// <summary>
        /// 获取群组详情
        /// </summary>
        public async Task<GroupDetailResponse> GetGroupDetailAsync(string userId, int groupId)
        {
            // 验证用户是否是群组成员
            var group = await _groupDal.GetGroupDetailAsync(groupId);
            if (group == null)
                throw new KeyNotFoundException("群组不存在");

            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            return new GroupDetailResponse
            {
                GroupId = group.Id,
                GroupName = group.GroupName,
                DescText = group.DescText,
                CreatedBy = group.CreateUserId,
                CreatedAt = group.CreateTime
            };
        }

        /// <summary>
        /// 加入群组
        /// </summary>
        public async Task JoinGroupAsync(string userId, int groupId)
        {
            // 验证群组是否存在
            var group = await _groupDal.GetGroupByIdAsync(groupId);
            if (group == null)
                throw new KeyNotFoundException("群组不存在");

            // 验证用户是否已经是群组成员
            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (isMember)
                throw new InvalidOperationException("您已经是该群组成员");

            await _memberDal.AddMemberAsync(new ChatGroupMember
            {
                ChatGroupId = groupId,
                UserId = userId,
                JoinTime = DateTime.Now
            });
        }

        /// <summary>
        /// 退出群组
        /// </summary>
        public async Task LeaveGroupAsync(string userId, int groupId)
        {
            // 验证用户是否是群组成员
            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            await _memberDal.RemoveMemberAsync(groupId, userId);
        }

        /// <summary>
        /// 获取群组成员
        /// </summary>
        public async Task<IEnumerable<GroupMemberResponse>> GetGroupMembersAsync(string userId, int groupId)
        {
            // 验证用户是否是群组成员
            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            var members = await _memberDal.GetGroupMembersAsync(groupId);
            return members.Select(m => new GroupMemberResponse
            {
                UserId = m.UserId,
                UserName = m.User.UserName
            });
        }

        /// <summary>
        /// 添加群组成员
        /// </summary>
        public async Task AddGroupMembersAsync(string userId, int groupId, List<string> memberIds)
        {
            // 验证用户是否是群组成员
            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            foreach (var memberId in memberIds)
            {
                if (!await _memberDal.IsMemberAsync(groupId, memberId))
                {
                    await _memberDal.AddMemberAsync(new ChatGroupMember
                    {
                        ChatGroupId = groupId,
                        UserId = memberId,
                        JoinTime = DateTime.Now
                    });
                }
            }
        }

        /// <summary>
        /// 移除群组成员
        /// </summary>
        public async Task RemoveGroupMemberAsync(string userId, int groupId, string memberId)
        {
            // 验证用户是否是群组成员
            var isMember = await _memberDal.IsMemberAsync(groupId, userId);
            if (!isMember)
                throw new UnauthorizedAccessException("您不是该群组成员");

            await _memberDal.RemoveMemberAsync(groupId, memberId);
        }

        /// <summary>
        /// 发送群组消息
        /// </summary>
        public async Task SendMessageAsync(int groupId, string senderId, string content)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(content))
                    throw new ArgumentException("消息内容不能为空");

                // 验证发送者是否是群组成员
                var isMember = await _memberDal.IsMemberAsync(groupId, senderId);
                if (!isMember)
                    throw new UnauthorizedAccessException("您不是该群组成员");

                var message = new ChatGroupMessage
                {
                    ChatGroupId = groupId,
                    SenderId = senderId,
                    Content = content,
                    SentTime = DateTime.Now
                };

                await _messageDal.AddMessageAsync(message);

                // 触发推送
                await _hubContext.Clients.Group($"Group_{groupId}")
                    .SendAsync("ReceiveMessage", new
                    {
                        SenderId = senderId,
                        Content = content,
                        SentTime = message.SentTime
                    });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "消息发送失败");
                throw new ChatException("消息发送失败", ex);
            }
        }
    }
}